/**
 * @file uart_dev.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2024-09-10
 *
 * @copyright Copyright (c) 2024
 *
*/
#include "stdio.h"
#include "stdlib.h"
#include "bflb_mtimer.h"
#include "bflb_gpio.h"
#include "bflb_uart.h"
#include "ring_buffer.h"
#include "log.h"
#include "FreeRTOS.h"
#include "task.h"
#include "uart_dev.h"
#include "device_ctrl.h"

#define DBG_TAG "UART"

static Ring_Buffer_Type uart_rx_rb;
static struct bflb_device_s* uart1;
static TaskHandle_t recv_data_task;
ra08_data_t __ra08_data;
static uint8_t uart_rx_buffer[256];

#define UART_ISR_NOTIFY_INDEX  0

static void stringToUid(const char* input, char* output, int uid_cnt) {
    if (input == NULL || output == NULL || strlen(input) !=  uid_cnt) {
        // 输入不合法，可以设置output为一个错误消息或留空  
        output[0] = '\0';
        return;
    }

    for (int i = 0, j = 0; i < uid_cnt; i += 2, j += 3) {
        // 转换每两个字符为一个十六进制数，并添加冒号（除了最后一个字节后）  
        output[j] = input[i];
        output[j + 1] = input[i + 1];

        // 如果不是最后两个字符，添加则冒号  
        if (i < 10) {
            output[j + 2] = ':';
        }
    }

    // 确保字符串以'\0'结尾  
    output[17] = '\0';
}
/**
 * @brief
 *
 * @param irq
 * @param arg
*/
static void uart1_isr(int irq, void* arg)
{
    uint32_t intstatus = bflb_uart_get_intstatus(uart1);
    uint8_t u8_data;

    if (intstatus & UART_INTSTS_RX_FIFO) {
        while (bflb_uart_rxavailable(uart1)) {
            u8_data = bflb_uart_getchar(uart1);
            Ring_Buffer_Write_Byte(&uart_rx_rb, u8_data);
        }
    }
    if (intstatus & UART_INTSTS_RTO) {

        while (bflb_uart_rxavailable(uart1)) {
            u8_data = bflb_uart_getchar(uart1);
            Ring_Buffer_Write_Byte(&uart_rx_rb, u8_data);
        }
        bflb_uart_int_clear(uart1, UART_INTCLR_RTO);
        /* notify to task */
        BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
        xTaskNotifyIndexedFromISR(recv_data_task, UART_ISR_NOTIFY_INDEX, 1, eSetValueWithOverwrite, &pxHigherPriorityTaskWoken);
        if (pxHigherPriorityTaskWoken) {
            portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
        }
    }

}
extern bool config_scr_del;
extern bool main_scr_del;
static void ra08_recv_data(void* arg)
{
    char* ra08_data = NULL;
    uint32_t len;
    int i = 0;
    while (1)
    {
        int ra08_data_status = ulTaskNotifyTakeIndexed(UART_ISR_NOTIFY_INDEX, pdTRUE, portMAX_DELAY);
        if (ra08_data_status)
        {
            ra08_data = pvPortMalloc(128);
            memset(ra08_data, 0, 128);
            len = Ring_Buffer_Get_Length(&uart_rx_rb);
            memset(ra08_data, 0, sizeof(ra08_data));
            Ring_Buffer_Read(&uart_rx_rb, ra08_data, len);
            //解析数据
            if (len>10) {
                char* lrw_uid_str = pvPortMalloc(32);
                char* lrw_temp_str = pvPortMalloc(32);
                char* lrw_humi_str = pvPortMalloc(32);

                memset(lrw_uid_str, 0, 32);
                memset(lrw_temp_str, 0, 32);
                memset(lrw_humi_str, 0, 32);
                //从逗号进行解析
                {
                    char* str_temp = strtok(ra08_data, ",");
                    // strncpy(ra08_datas[i], str_temp, strlen(str_temp));
                    strncpy(lrw_uid_str, str_temp, strlen(str_temp));
                    // 使用 NULL 作为第一个参数来继续获取标记  
                    str_temp = strtok(NULL, ",");
                    strncpy(lrw_temp_str, str_temp, strlen(str_temp));
                    // i++;
                    str_temp = strtok(NULL, ",");
                    strncpy(lrw_humi_str, str_temp, strlen(str_temp));

                }
                //解析uid
                if (lrw_uid_str!=NULL) {
                    char* str_uid = strtok(lrw_uid_str, ":");
                    str_uid = strtok(NULL, ":");
                    memset(__ra08_data.dev_uid, 0, 16);
                    // memcpy(__ra08_data.dev_uid, str_uid, 16);
                    strncpy(__ra08_data.dev_uid, str_uid, 16);

                }
                //解析温度
                if (lrw_temp_str!=NULL)
                {
                    char* str_temp = strtok(lrw_temp_str, ":");
                    str_temp = strtok(NULL, ":");
                    __ra08_data.temperature = (double)atof(str_temp);

                    __ra08_data.temperature_F = __ra08_data.temperature/17.2222222;
                }
                // //解析湿度
                if (lrw_humi_str)
                {
                    char* str_humi = strtok(lrw_humi_str, ":");
                    str_humi = strtok(NULL, ":");
                    __ra08_data.humidity = atoi(str_humi);
                }
                // printf("%s\n\r", str_uid);
                vPortFree(lrw_uid_str);
                vPortFree(lrw_temp_str);
                vPortFree(lrw_humi_str);
            }
            // LOG_I("UID:%s  temp:%f ℃ humi:%d%%", __ra08_data.dev_uid, __ra08_data.temperature, __ra08_data.humidity);
            if (!main_scr_del&&config_scr_del)
                device_send_state_notify(DEVICE_STATE_LRW_DATA_UPDATE, false);
        }

        if (ra08_data!=NULL)
            vPortFree(ra08_data);

    }

}
/**
 * @brief
 *
*/
void uart1_init()
{
    struct bflb_device_s* gpio;

    gpio = bflb_device_get_by_name("gpio");
    bflb_gpio_uart_init(gpio, GPIO_PIN_18, GPIO_UART_FUNC_UART1_TX);
    bflb_gpio_uart_init(gpio, GPIO_PIN_19, GPIO_UART_FUNC_UART1_RX);

    struct bflb_uart_config_s cfg;
    cfg.baudrate = 115200;
    cfg.data_bits = UART_DATA_BITS_8;
    cfg.stop_bits = UART_STOP_BITS_1;
    cfg.parity = UART_PARITY_NONE;
    cfg.flow_ctrl = 0;
    cfg.tx_fifo_threshold = 7;
    cfg.rx_fifo_threshold = 7;

    uart1 = bflb_device_get_by_name("uart1");

    bflb_uart_init(uart1, &cfg);
    bflb_uart_rxint_mask(uart1, false);
    bflb_irq_attach(uart1->irq_num, uart1_isr, NULL);
    bflb_irq_enable(uart1->irq_num);
    Ring_Buffer_Init(&uart_rx_rb, uart_rx_buffer, sizeof(uart_rx_buffer), NULL, NULL);
    xTaskCreate(ra08_recv_data, "recv data", 1024*2, NULL, 6, &recv_data_task);
}